package redis.clients.jedis;

import redis.clients.jedis.exceptions.JedisDataException;

import java.util.ArrayList;
import java.util.List;

/**
 * Transaction is nearly identical to Pipeline, only differences are the multi/discard behaviors
 */
public class Transaction extends MultiKeyPipelineBase {

    protected boolean inTransaction = true;

    protected Transaction(){
        // client will be set later in transaction block
    }

    public Transaction(final Client client) {
        this.client = client;
    }

    @Override
    protected Client getClient(String key) {
        return client;
    }

    @Override
    protected Client getClient(byte[] key) {
        return client;
    }

    public List<Object> exec() {
        client.exec();
        client.getAll(1); // Discard all but the last reply

        List<Object> unformatted = client.getObjectMultiBulkReply();
        if (unformatted == null) {
            return null;
        }
        List<Object> formatted = new ArrayList<Object>();
        for (Object o : unformatted) {
            try {
                formatted.add(generateResponse(o).get());
            } catch (JedisDataException e) {
                formatted.add(e);
            }
        }
        return formatted;
    }

    public List<Response<?>> execGetResponse() {
        client.exec();
        client.getAll(1); // Discard all but the last reply

        List<Object> unformatted = client.getObjectMultiBulkReply();
        if (unformatted == null) {
            return null;
        }
        List<Response<?>> response = new ArrayList<Response<?>>();
        for (Object o : unformatted) {
            response.add(generateResponse(o));
        }
        return response;
    }

    public String discard() {
        client.discard();
        client.getAll(1); // Discard all but the last reply
        inTransaction = false;
        clean();
        return client.getStatusCodeReply();
    }

}